/*******************************************************
 Windows HID simplification

 Alan Ott
 Signal 11 Software

 8/22/2009

 Copyright 2009, All Rights Reserved.
 
 This contents of this file may be used by anyone
 for any reason without any conditions and may be
 used as a starting point for your own applications
 which use HIDAPI.
 ********************************************************/

#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include "hidapi.h"

// Headers needed for sleeping.
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

int
main(int argc,char* argv[])
{
  int res;
  unsigned char buf[256];
#define MAX_STR 255
  wchar_t wstr[MAX_STR];
  hid_device *handle;
  int i;

#ifdef WIN32
  UNREFERENCED_PARAMETER(argc);
  UNREFERENCED_PARAMETER(argv);
#endif

  struct hid_device_info *devs, *cur_dev;

  devs = hid_enumerate(0x0,0x0);
  cur_dev = devs;
  while(cur_dev)
  {
    printf(
	"Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls",
	cur_dev->vendor_id,cur_dev->product_id,cur_dev->path,
	cur_dev->serial_number);
    printf("\n");
    printf("  Manufacturer: %ls\n",cur_dev->manufacturer_string);
    printf("  Product:      %ls\n",cur_dev->product_string);
    printf("  Release:      %hx\n",cur_dev->release_number);
    printf("  Interface:    %d\n",cur_dev->interface_number);
    printf("\n");
    cur_dev = cur_dev->next;
  }
  hid_free_enumeration(devs);

  // Set up the command buffer.
  memset(buf,0x00,sizeof(buf));
  buf[0] = 0x01;
  buf[1] = 0x81;

  // Open the device using the VID, PID,
  // and optionally the Serial number.
  ////handle = hid_open(0x4d8, 0x3f, L"12345");
  handle = hid_open(0x2047,0x0301,NULL);
  if(!handle)
  {
    printf("unable to open device\n");
    return 1;
  }

  // Read the Manufacturer String
  wstr[0] = 0x0000;
  res = hid_get_manufacturer_string(handle,wstr,MAX_STR);
  if(res < 0)
    printf("Unable to read manufacturer string\n");
  printf("Manufacturer String: %ls\n",wstr);

  // Read the Product String
  wstr[0] = 0x0000;
  res = hid_get_product_string(handle,wstr,MAX_STR);
  if(res < 0)
    printf("Unable to read product string\n");
  printf("Product String: %ls\n",wstr);

  // Read the Serial Number String
  wstr[0] = 0x0000;
  res = hid_get_serial_number_string(handle,wstr,MAX_STR);
  if(res < 0)
    printf("Unable to read serial number string\n");
  printf("Serial Number String: (%d) %ls",wstr[0],wstr);
  printf("\n");

  // Read Indexed String 1
  wstr[0] = 0x0000;
  res = hid_get_indexed_string(handle,1,wstr,MAX_STR);
  if(res < 0)
    printf("Unable to read indexed string 1\n");
  printf("Indexed String 1: %ls\n",wstr);

  // Set the hid_read() function to be non-blocking.
  hid_set_nonblocking(handle,1);
#if 0	
  // Try to read from the device. There shoud be no
  // data here, but execution should not block.
  res = hid_read(handle, buf, 17);

  // Send a Feature Report to the device
  buf[0] = 0x2;
  buf[1] = 0xa0;
  buf[2] = 0x0a;
  buf[3] = 0x00;
  buf[4] = 0x00;
  res = hid_send_feature_report(handle, buf, 17);
  if (res < 0)
  {
    printf("Unable to send a feature report.\n");
  }

  memset(buf,0,sizeof(buf));

  // Read a Feature Report from the device
  buf[0] = 0x2;
  res = hid_get_feature_report(handle, buf, sizeof(buf));
  if (res < 0)
  {
    printf("Unable to get a feature report.\n");
    printf("%ls", hid_error(handle));
  }
  else
  {
    // Print out the returned buffer.
    printf("Feature Report\n   ");
    for (i = 0; i < res; i++)
    printf("%02hhx ", buf[i]);
    printf("\n");
  }

  memset(buf,0,sizeof(buf));
#endif
  // Toggle LED (cmd 0x80). The first byte is the report number (0x1).

  unsigned char tmpbuf[64] =
  { 0 };
  tmpbuf[0] = 0x3f;
  tmpbuf[1] = 0x1;
  tmpbuf[2] = 0x35;
  res = hid_write(handle,tmpbuf,64);
  if(res < 0)
  {
    printf("Unable to write()\n");
    printf("Error: %ls\n",hid_error(handle));
  }

  // Request state (cmd 0x81). The first byte is the report number (0x1).
  memset(tmpbuf,0,sizeof(tmpbuf));
  tmpbuf[0] = 0x3f;
  tmpbuf[1] = 0x5;
  tmpbuf[2] = 'a', buf[3] = 'b', buf[4] = 'c', tmpbuf[5] = 'd', tmpbuf[6] = 'e';
  res = hid_write(handle,tmpbuf,64);
  if(res < 0)
    printf("Unable to write() (2)\n");

  // Read requested state. hid_read() has been set to be
  // non-blocking by the call to hid_set_nonblocking() above.
  // This loop demonstrates the non-blocking nature of hid_read().
  res = 0;
  memset(tmpbuf,0,sizeof(tmpbuf));
  while(res == 0)
  {
    res = hid_read(handle,tmpbuf,sizeof(tmpbuf));
    if(res == 0)
      printf("waiting...\n");
    if(res < 0)
      printf("Unable to read()\n");
#ifdef WIN32
    Sleep(500);
#else
    usleep(500 * 1000);
#endif
  }

  printf("Data read:\n   ");
  // Print out the returned buffer.
  for(i = 0;i < res;i++)
    printf("%c ",tmpbuf[i]);
  printf("\n");

  hid_close(handle);

  /* Free static HIDAPI objects. */
  hid_exit();

#ifdef WIN32
  system("pause");
#endif

  return 0;
}
